package http;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.InputStream;
import java.net.URI;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;

public class SSLDemo {

    /**
     * 通过读取证书来访问https地址
     * @param url https地址
     * @throws Exception 任何异常
     */
    public static void readCRT(String url) throws Exception {
        CloseableHttpClient client = null;
        CloseableHttpResponse response = null;
        URI uri = new URI(url);
        SSLContext context = getSSLContext(uri);
        try{
            client = HttpClients.custom()
                    .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)//如果是IP地址，这里忽略主机名的校验
                    .setSSLContext(context).build();
            response = client.execute(new HttpGet(url));
            System.out.println(response);
        }finally {
            if(client!=null) {
                client.close();
            }
            if(response!=null) {
                response.close();
            }
        }
    }

    /**
     * 读取证书后放入keystore
     * @param uri https的url
     * @return SSLContext
     * @throws Exception 任何异常
     */
    private static SSLContext getSSLContext(URI uri) throws Exception {
        InputStream in = Class.class.getResourceAsStream("/crt/test.crt");
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        Certificate certificate = cf.generateCertificate(in);
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null,null);
        String host = uri.getHost();
        keyStore.setCertificateEntry(host,certificate);
        TrustManagerFactory tf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tf.init(keyStore);
        SSLContext tls = SSLContext.getInstance("TLS");
        tls.init(null,tf.getTrustManagers(),null);
        return tls;
    }
}
